/** @jsxImportSource @emotion/react */
import { createElement, HTMLAttributes, useEffect, useState, type FC } from 'react';
import classNames from 'classnames';
import { ratingDefaultProps } from './defaultProps';
import type { RatingOptions } from './type';

export interface RatingProps extends RatingOptions, Omit<HTMLAttributes<HTMLDivElement>, 'color'> {}

const Rating: FC<RatingProps> = (props) => {
  const { className, ui, max, icon, value, color, size, disabled, forwardedRef, ...ratingProps } = props;
  const [selected, setSelected] = useState(false);
  const [valueAs, setValueAs] = useState(value);
  const [selectIndex, setSelectIndex] = useState<number>();
  const maxAs = max && max > 0 ? max : 1;

  useEffect(() => {
    if (selectIndex === undefined) {
      setSelected(false);
    } else {
      setSelected(true);
    }
  }, [selectIndex]);

  const icons = [];
  for (let i = 0; i < maxAs; i++) {
    icons.push(
      <i
        key={i}
        className={classNames(icon, 'icon', {
          selected: selectIndex !== undefined && (selectIndex > i || selectIndex === i),
          partial: !Number.isInteger(valueAs) && i === Math.floor(valueAs || 0),
          active: valueAs && valueAs > 0 && valueAs > i,
        })}
        onMouseEnter={() => setSelectIndex(i)}
        onMouseLeave={() => setSelectIndex(undefined)}
        onClick={() => setValueAs(i + 1)}
        css={
          !Number.isInteger(valueAs) && i === Math.floor(valueAs || 0) && { '--full': `${((valueAs || 0) % 1) * 100}%` }
        }
      />,
    );
  }

  return createElement(
    'div',
    {
      ref: forwardedRef,
      className: classNames({ ui, disabled, selected }, color, size, 'rating', className),
      ...ratingProps,
    },
    icons,
  );
};

Rating.displayName = 'Rating';
Rating.defaultProps = ratingDefaultProps;

export default Rating;
